﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MIPS_Simulator
{
    public partial class Form1 : Form
    {
        Memory memory;
        string[] s;
        InstructionMemory instMemory;
        Registers regs;
        ALU alu;
        Control control;
        short PC;
        ProgramCounter pc;

        public Form1()
        {
            InitializeComponent();
            PC = 0;
            regs = new Registers();
            memory = new Memory();
            instMemory = new InstructionMemory();
            alu = new ALU();
            pc = new ProgramCounter(instMemory, alu);
            control = new Control(pc, regs, memory, alu);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                s = textBox1.Text.Split('\n');
                if (s[0].Split(' ').Length > 2 || !(s[0].Split(' '))[0].ToLower().Equals("org"))
                    throw new Exception();
                short PC = short.Parse(s[0].Substring(4));
                pc.NextInstruction = PC;
                int i, j;
                for (i = PC, j = 1; j < s.Length; i++, j++)
                {
                    instMemory.storeWord(s[j], i);

                }


                textBox5.Text = "Compiled Successfully";
            }
            catch (Exception ex)
            {
                textBox5.Text="Compilation Error";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            initialize(s);
            while(true)
            {

                if (!pc.Fetch())
                    break;
                
                pc.Compile();

                if (pc.Instruction.ToArray()[0] == "end\r" || pc.Instruction.ToArray()[0] == "end")
                {
                    break;
                }

                try
                {
                    control.Compile(pc.Instruction);
                }
                catch (Exception ex)
                {
                    textBox5.Text = "Invalid command excpetion";
                }

                control = new Control(pc, regs, memory, alu);
                
            }

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < 32; i++)
            {
                if(comboBox1.Text.Equals("Register "+i))
                    textBox2.Text = ""+regs.loadReg(((short)i));
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            textBox1.Clear();
            textBox2.Clear();
            textBox3.Clear();
            textBox4.Clear();
            textBox5.Clear();
            textBox6.Clear();
            PC = 0;
            regs = new Registers();
            memory = new Memory();
            instMemory = new InstructionMemory();
            alu = new ALU();
            pc = new ProgramCounter(instMemory, alu);
            control = new Control(pc, regs, memory, alu);
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button7_Click(object sender, EventArgs e)
        {
            try
            {
                memory.MemRead = true;
                textBox3.Text = "" + memory.loadWord(long.Parse(textBox4.Text));
                memory.MemRead = false;
            }
            catch (Exception ex) { }

        }

        public void initialize(string[] s)
        {
            string[] sR = reverseArray(s);
            string[] command;
            try
            {
                memory.MemWrite = true;

                for (int i = 0; i < s.Length; i++)
                {

                    if (sR[i].ToLower().Equals("end\r") || sR[i].ToLower().Equals("end"))
                    {
                        break;
                    }
                    command = sR[i].Split(' ');
                    System.Diagnostics.Debug.WriteLine("i = " + i);
                    memory.storeWord(Convert.ToInt64(command[1]), Convert.ToInt64(command[0]));
                }
                memory.MemWrite = false;
            }
            catch (Exception e)
            {
                textBox5.Text = "An error occured. Most likely you forgot to write \"end\" in the code";
            }
        }

        private string[] reverseArray(string[] myString)
        {
            string[] result = new string[myString.Length];
            for (int i = 0; i < myString.Length; i++)
            {
                result[i] = myString[myString.Length - (i + 1)];
            }

            return result;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            textBox6.Text = pc.ClockCycles-1+"";
        }

    }
}
